package com.ruoyi.system.apiService.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.apiResult.ApiRe;
import com.ruoyi.common.apiResult.ChannelSupervise;
import com.ruoyi.common.apiResult.ZhtcRe;
import com.ruoyi.common.cache.CacheComponent;
import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
import com.ruoyi.common.utils.BeanUtil;
import com.ruoyi.common.utils.GeneratorUtil;
import com.ruoyi.system.aikeService.ToZhtcApiService;
import com.ruoyi.system.apiService.CouponService;
import com.ruoyi.system.apiService.HomeParkService;
import com.ruoyi.system.apiService.OrderService;
import com.ruoyi.system.apiService.ZhtcService;
import com.ruoyi.system.domain.ZsyyChannelInfo;
import com.ruoyi.system.domain.ZsyyParkEnter;
import com.ruoyi.system.domain.ZsyyParkLeave;
import com.ruoyi.system.dto.CouponByParkCarDTO;
import com.ruoyi.system.dto.SendplateticketQuery;
import com.ruoyi.system.mapper.CommonMapper;
import com.ruoyi.system.mapper.ZsyyParkEnterMapper;
import com.ruoyi.system.mapper.ZsyyParkLeaveMapper;
import com.ruoyi.system.service.impl.ZsyyUserCouponServiceImpl;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ZhtcServiceImpl implements ZhtcService {
	@Value("${etc.apiurl}")
	private String etcUrl;
	@Value("${etc.merchantNo}")
	private String merchantNo;
	@Value("${spring.profiles.active}")
	private String active;

	@Autowired
	private CacheComponent cacheComponent;
	@Autowired
	private CommonMapper commonMapper;
	@Autowired
	private ChannelSupervise channelSupervise;

	@Autowired
	private CouponService couponService;
	@Autowired
	private ZsyyUserCouponServiceImpl userCouponService;
	@Autowired
	private ZsyyParkEnterMapper parkEnterMapper;

	@Autowired
	private HomeParkService homeParkService;

	@Autowired
	private ZsyyParkLeaveMapper parkLeaveMapper;
	@Autowired
	private ToZhtcApiService toZhtcApiService;
	@Autowired
	private OrderService orderService;

	@Override
	public ZhtcRe addParkEnter(ZsyyParkEnter parkEnter) throws Exception {
		String gangtingKey = parkEnter.getParkCode()+"_"+parkEnter.getEnterChannelCode();
		String gangting = cacheComponent.getRaw(gangtingKey);
		if(gangting!=null){
			long gangtingId = Long.parseLong(gangting.substring(0,gangting.indexOf("_")));
			String gangtingName = gangting.substring(gangting.indexOf("_")+1);
			parkEnter.setGangtingId(gangtingId);
			parkEnter.setGangtingName(gangtingName);
		}
		if(active.equals("test"))
			Thread.sleep(100);
		boolean inFlg = "reportCarIn".equals(parkEnter.getCmd());
		if(!inFlg){
			channelSupervise.uriSend("/websocket/"+parkEnter.getParkCode()+"/"+parkEnter.getEnterChannelCode(),parkEnter.getEnterCarLicenseNumber()+"_1");
		}
		parkEnter.setType(1);
		if(parkEnter.getEnterImageArray()!=null){
			//处理入场车的图片
			List<Map> list = JSON.parseArray(parkEnter.getEnterImageArray(),Map.class);
			if(list.size()>0){
				parkEnter.setCarImage((String)list.get(0).get("carImage"));
				parkEnter.setPlateImage((String)list.get(0).get("plateImage"));
			}
		}
		ZsyyParkEnter pe = null;
		boolean fla1 = !StringUtils.isEmpty(parkEnter.getSelfInRandomCode());
		boolean fla2 = !StringUtils.isEmpty(parkEnter.getParkingCode());
		Map params = new HashMap();
		String sql1 = " select * FROM `zsyy_park_enter` WHERE status =1 and car_license_number = #{carNum} and createtime >#{createtime}  limit 1";
		params.put("sql",sql1);
		params.put("createtime",new Date(new Date().getTime()-1000*60*30));
		params.put("carNum",parkEnter.getCarLicenseNumber());
		pe = parkEnterMapper.getEnty(params);
		//特殊处理橙堡数据
		if ("TDZN/100760P5757".equals(parkEnter.getParkCode())) {
			if(pe!=null){
				pe.setBEntertime(new Date());
				pe.setChannelId(Long.parseLong(parkEnter.getEnterChannelCode()));
				pe.setLockKey(parkEnter.getParkingCode());
				parkEnterMapper.updateById(pe);
			}else {
				parkEnter.setChannelId(Long.parseLong(parkEnter.getEnterChannelCode()));
				parkEnter.setLockKey(parkEnter.getParkingCode());
				parkEnter.setParkCode("2KST6MLE");
				parkEnterMapper.insert(parkEnter);
			}
			return new ZhtcRe();
		}

		if(pe==null&&fla2){
//			pe =new ZsyyParkEnter();
//			pe.setParkingCode(parkEnter.getParkingCode());
			LambdaQueryWrapper<ZsyyParkEnter> lqw = Wrappers.lambdaQuery();
			lqw.eq(ZsyyParkEnter::getParkCode,parkEnter.getParkCode());
			pe = parkEnterMapper.selectOne(lqw);
//               if(pe==null||pe.getEtcStatus()==1){
//                   //etc
//                   Map paramM = new HashMap();
//                   paramM.put("merchantNo",merchantNo);
//                   paramM.put("vehiclePlate",parkEnter.getCarLicenseNumber());
//                   paramM.put("serviceType",2);
//                   paramM.put("entranceNo",parkEnter.getEnterChannelCode());
//                   paramM.put("entranceName",parkEnter.getEnterChannelName());
//                   String params = JSON.toJSONString(paramM);
//                   String resultStr =
//                           HttpRequest.post(etcUrl+"/parkingLotSystem/etcCarEnter")
//                                   .header("Accept","application/json")
//                                   .header("Content-Type","application/json;charset=utf-8")
//                                   .body(params)
//                                   .execute().body();
//                   System.out.println("etc进场返回数据："+resultStr);
//                   parkEnter.setEtcStatus(2);
//               }

		}else if(pe==null&&fla1){
//			pe =new ZsyyParkEnter();
			LambdaQueryWrapper<ZsyyParkEnter> lqw = Wrappers.lambdaQuery();
			lqw.eq(ZsyyParkEnter::getStatus,1);
			lqw.eq(ZsyyParkEnter::getParkCode,parkEnter.getParkCode());
			lqw.eq(ZsyyParkEnter::getSelfInRandomCode,parkEnter.getSelfInRandomCode());
//			pe.setParkCode(parkEnter.getParkCode());
//			pe.setStatus(1);
//			pe.setSelfInRandomCode(parkEnter.getSelfInRandomCode());
			pe = parkEnterMapper.selectOne(lqw);
		}

		String userIds = "";
		if(!StringUtils.isEmpty(parkEnter.getCarLicenseNumber())){
			Map param = new HashMap();
			String sql = "SELECT user_id FROM `zsyy_park_car` WHERE  car_license_number  = #{car_license_number}";
			param.put("car_license_number",parkEnter.getCarLicenseNumber());
//            param.put("parkCode",parkEnter.getParkCode());
			param.put("sql",sql);
			List<Object> list = commonMapper.findObjList(param);

			for ( Object o:list) {
				userIds+=o+",";
			}
		}
		if(parkEnter.getUserId()!=null&&parkEnter.getUserId()>0&&userIds.indexOf(parkEnter.getUserId()+"")==-1){
			userIds+=parkEnter.getUserId()+",";
		}

		if(!StringUtils.isEmpty(userIds)){
			parkEnter.setUserIds(userIds);
		}
		parkEnter.setChannelId(null);
		if(pe!=null&&pe.getId()!=null){
			String carCode = pe.getCarLicenseNumber();
			BeanUtil.copyPropertiesIgnoreNull(parkEnter,pe);
			if(carCode!=null&&carCode.trim().length()==7){
				pe.setCarLicenseNumber(carCode);
			}
			parkEnterMapper.updateById(pe);
		}else{
			parkEnterMapper.insert(parkEnter);
		}

//        String enterCarLicenseNumber = parkEnter.getEnterCarLicenseNumber();//车牌号
//        if(!StringUtils.isEmpty(enterCarLicenseNumber)){
//            Map param = new HashMap();
//            String sql = "SELECT * FROM `zsyy_user_month_card` WHERE car_code = #{enterCarLicenseNumber} AND begin_time<NOW() AND end_time>NOW() AND STATUS = 1";
//            param.put("enterCarLicenseNumber",enterCarLicenseNumber);
//            param.put("sql",sql);
//            List<Map> list = commonMapper.findList(param);
//            if(list.size()>0){
//
//            }
//        }
		return new ZhtcRe();
	}

	@Override
	public ZhtcRe addParkLeave(ZsyyParkLeave parkLeave) throws Exception {

		String gangtingKey = parkLeave.getParkCode()+"_"+parkLeave.getLeaveChannelCode();
		String gangting = cacheComponent.getRaw(gangtingKey);
		if(gangting!=null){
			long gangtingId = Long.parseLong(gangting.substring(0,gangting.indexOf("_")));
			String gangtingName = gangting.substring(gangting.indexOf("_")+1);
			parkLeave.setGangtingId(gangtingId);
			parkLeave.setGangtingName(gangtingName);
		}

		if(active.equals("test"))
			Thread.sleep(100);


		if(parkLeave.getLeaveImageArray()!=null){
			//处理出场车的图片
			List<Map> list = JSON.parseArray(parkLeave.getLeaveImageArray(),Map.class);
			if(list.size()>0){
				parkLeave.setCarImage((String)list.get(0).get("carImage"));
				parkLeave.setPlateImage((String)list.get(0).get("plateImage"));
			}
		}
		if(parkLeave.getEnterImageArray()!=null){
			//处理出场车的图片
			List<Map> list = JSON.parseArray(parkLeave.getEnterImageArray(),Map.class);
			if(list.size()>0){
				parkLeave.setEnCarImage((String)list.get(0).get("carImage"));
				parkLeave.setEnPlateImage((String)list.get(0).get("plateImage"));
			}
		}
		//是否是离场，不是的话就是预离场
		parkLeave.setParkingTime(this.parkingTime(parkLeave.getEnterTime(),parkLeave.getLeaveTime()));
		boolean leveFlg = "reportCarOut".equals(parkLeave.getCmd());//true离场，false预离场

		if(!leveFlg){
			parkLeave.setLeaveStatus(0);
			channelSupervise.uriSend("/websocket/"+parkLeave.getParkCode()+"/"+parkLeave.getLeaveChannelCode(),parkLeave.getLeaveCarLicenseNumber()+"_2");
		}else{
			Map params = new HashMap();
			String sql1 = " select * FROM `zsyy_park_enter` WHERE status =1 and parking_code = #{parkingCode} order by id desc  limit 1";
			params.put("sql",sql1);
			params.put("parkingCode",parkLeave.getParkingCode());
			ZsyyParkEnter pe = parkEnterMapper.getEnty(params);
			if(pe!=null){
				parkLeave.setType(pe.getType());
			}
			parkLeave.setLeaveStatus(1);
		}
		ZsyyParkLeave ple = new ZsyyParkLeave();
		ple.setParkCode(parkLeave.getParkCode());
		Map params1 = new HashMap();
		String sql = " select * FROM `zsyy_park_leave` WHERE leave_car_license_number = #{carNum} and createtime >#{createtime}  limit 1";
		params1.put("sql",sql);
		params1.put("createtime",new Date(new Date().getTime()-1000*60*10));
		params1.put("carNum",parkLeave.getLeaveCarLicenseNumber());
		ple = parkLeaveMapper.getEnty(params1);
		//特殊处理橙堡数据
		String parkCode = parkLeave.getParkCode();
		if ("TDZN/100760P5757".equals(parkCode)||"2KST6MLE".equals(parkCode)) {
			//城堡停车场
			Map params = new HashMap();
			String sql1 = " select * FROM `zsyy_park_enter` WHERE status =1 and car_license_number = #{carNum} order by id desc  limit 1";
			params.put("sql",sql1);
//            params.put("createtime",new Date(new Date().getTime()-1000*60*25));
			params.put("carNum",parkLeave.getCarLicenseNumber());
			ZsyyParkEnter pe = parkEnterMapper.getEnty(params);

			if(pe!=null){

				long now = new Date().getTime()-1000*60*30;
				long enTime = 0;
				if(pe.getBEntertime()==null){
					enTime = pe.getEnterTime().getTime();
				}else {
					enTime = pe.getBEntertime().getTime();
				}
				if(now<enTime){
					pe.setBEntertime(new Date());
					pe.setType(2);
					parkEnterMapper.updateById(pe);
				}

				parkLeave.setParkingCode(pe.getParkingCode());
				if(ple==null){
					/*ple = new ZsyyParkLeave();
					ple.setParkingCode(pe.getParkingCode());
					ple = parkLeaveMapper.selectOne(ple);*/
					LambdaQueryWrapper<ZsyyParkLeave> lqw = Wrappers.lambdaQuery();
					lqw.eq(ZsyyParkLeave::getParkingCode,pe.getParkingCode());
					ple = parkLeaveMapper.selectOne(lqw);
				}
				if(ple==null && !StringUtils.isEmpty(pe.getLockKey())){
					/*ple = new ZsyyParkLeave();
					ple.setParkingCode(pe.getLockKey());
					ple = parkLeaveMapper.selectOne(ple);*/
					LambdaQueryWrapper<ZsyyParkLeave> lqw = Wrappers.lambdaQuery();
					lqw.eq(ZsyyParkLeave::getParkingCode,pe.getParkingCode());
					ple = parkLeaveMapper.selectOne(lqw);
				}
			}

			if("2KST6MLE".equals(parkCode)){
				//保证贵阳的设备的通道id能设置到channelId字段中
				parkLeave.setChannelId(null);
			}else {
				parkLeave.setParkCode("2KST6MLE");
				parkLeave.setChannelId(Long.parseLong(parkLeave.getLeaveChannelCode()));
			}

			if(leveFlg&&"2KST6MLE".equals(parkCode)){
				//更新进场状态
				ZsyyParkLeave pe1 = new ZsyyParkLeave();
				pe1.setLeaveStatus(2);
				pe1.setLeaveTime(parkLeave.getLeaveTime());
				parkLeaveMapper.update(pe1,new QueryWrapper<ZsyyParkLeave>().eq("park_code",parkCode).eq("parking_code",parkLeave.getParkingCode()));

			}

			if(ple!=null&&ple.getId()!=null){

				if("2KST6MLE".equals(parkCode)){
					//不要去把收费更新
					if(!StringUtils.isEmpty(parkLeave.getTotalAmount())){
						double totalAmount = parkLeave.getTotalAmount().doubleValue();
						if(totalAmount<=0){
							parkLeave.setTotalAmount(null);
						}
					}
					if(!StringUtils.isEmpty(parkLeave.getAmountReceivable())){
						double amountReceivable = parkLeave.getAmountReceivable().doubleValue();
						if(amountReceivable<=0){
							parkLeave.setAmountReceivable(null);
						}
					}
					if(!StringUtils.isEmpty(parkLeave.getDiscountAmount())){
						double discountAmount = parkLeave.getDiscountAmount().doubleValue();
						if(discountAmount<=0){
							parkLeave.setDiscountAmount(null);
						}
					}
					if(!StringUtils.isEmpty(parkLeave.getActualReceivable())){
						double actualReceivable = parkLeave.getActualReceivable().doubleValue();
						if(actualReceivable<=0){
							parkLeave.setActualReceivable(null);
						}
					}
				}
				BeanUtil.copyPropertiesIgnoreNull(parkLeave,ple);
				ple.setLockKey(null);
				parkLeaveMapper.updateById(ple);
			}else{
				parkLeaveMapper.insert(parkLeave);
			}
			return new ZhtcRe();
		}else{
			//其他停车场
			if(leveFlg){
				if(ple==null&&!StringUtils.isEmpty(parkLeave.getParkingCode())){
					LambdaQueryWrapper<ZsyyParkLeave> lqw = Wrappers.lambdaQuery();
					lqw.eq(ZsyyParkLeave::getParkingCode,parkLeave.getParkingCode());
					ple = parkLeaveMapper.selectOne(lqw);
				}
				LambdaQueryWrapper<ZsyyParkLeave> lqw = Wrappers.lambdaQuery();
				lqw.eq(ZsyyParkLeave::getParkingCode,parkLeave.getParkingCode());

				List<ZsyyParkEnter> pens = parkEnterMapper.selectList(new QueryWrapper<ZsyyParkEnter>().eq("parking_code",parkLeave.getParkingCode()));
				ZsyyParkEnter pen = null;
				if(pens.size()>0){
					pen =pens.get(0);
				}
				if(pen!=null){
					parkLeave.setCarLicenseNumber(pen.getCarLicenseNumber());
				}
			}else if(parkLeave.getAmountReceivable().doubleValue()>0){
				//调取是否有优惠券抵扣
				this.couponPlay(parkLeave);
			}

			if(ple!=null&&ple.getId()!=null){
				BeanUtil.copyPropertiesIgnoreNull(parkLeave,ple);
				ple.setLockKey(null);
				parkLeaveMapper.updateById(ple);
			}else{
				parkLeaveMapper.insert(parkLeave);
			}
			if(leveFlg){
				//更新进场状态
				ZsyyParkLeave pe = new ZsyyParkLeave();
				pe.setLeaveStatus(2);
				pe.setLeaveTime(parkLeave.getLeaveTime());
				parkLeaveMapper.update(pe,new QueryWrapper<ZsyyParkLeave>().eq("park_code",parkCode).eq("parking_code",parkLeave.getParkingCode()));

			}
			return new ZhtcRe();
		}


	}

	@Override
	public ApiRe isOpenAutoPay(Map dataM) throws Exception {
		ApiRe re = new ApiRe();
		String leaveCarLicenseNumber = dataM.get("leaveCarLicenseNumber").toString();
		String leaveChannelCode = dataM.get("leaveChannelCode").toString();
		String parkCode = dataM.get("parkCode").toString();
		int amountReceivable = (int)(Double.parseDouble(dataM.get("amountReceivable").toString())*100);
		if(amountReceivable<=0){
			return re;
		}
		Map paramPay = new HashMap();
		String sqlPay = "SELECT t1.id,t1.balance FROM `t_user` t1 JOIN `zsyy_park_car` t2 ON t1.id = t2.user_id WHERE t1.status = 1 AND t1.auto_pay_status=2 AND t2.car_license_number=#{carLicenseNumber}";
		paramPay.put("carLicenseNumber",leaveCarLicenseNumber);
		paramPay.put("sql",sqlPay);
		List<Map> listPay = commonMapper.findList(paramPay);
		int balanceR = 0;
		long userIdR = 0;
		if(listPay.size()>0){
			for (Map m :
				listPay) {
				int balance = Integer.parseInt(m.get("balance").toString());
				if(balance>amountReceivable){
					balanceR =balance;
					userIdR = Long.parseLong(m.get("id").toString());
					break;
				}
			}
			if(balanceR>0){
				Map addParam = new HashMap();
				addParam.put("userId",userIdR);
				Map param = new HashMap();
				param.put("parkCode",parkCode);
				param.put("carCode",leaveCarLicenseNumber);
				String feeReStr = toZhtcApiService.privateApi("getParkFee", JSON.toJSONString(param),addParam);
				ApiRe feeRe = JSON.parseObject(feeReStr,ApiRe.class);
				if(feeRe.getCode()==200){
					Map orderData = (Map)((Map)feeRe.getData()).get("data");
					ApiRe payRe = orderService.balancePay(orderData.get("orderNo").toString(),userIdR);
					if(payRe.getCode()==200){
						return re;
					}
				}
			}
		}

		return re;
	}

	@Override
	public ZsyyParkEnter getParkEnter(ZsyyParkEnter pe) {
		LambdaQueryWrapper<ZsyyParkEnter> lqw = Wrappers.lambdaQuery();
		lqw.eq(ZsyyParkEnter::getStatus,1);
		ZsyyParkEnter peR = parkEnterMapper.selectOne(lqw);
		return peR;
	}

	@Override
	public String getStreamUrl(String channelCode) {
		String sql = "SELECT t2.stream_url,t2.rtsp_url from zsyy_channel_info t1 join zsyy_camera t2 on t1.camera_id = t2.id WHERE t1.channel_code = #{channelCode}";
		Map param = new HashMap();
		param.put("channelCode",channelCode);
		param.put("sql",sql);
		Map re = parkLeaveMapper.getMap(param);
		if(re!=null){
			return JSON.toJSONString(re);
		}
		return null;
	}

	public String parkingTime(Date startTime,Date endTime){
		long min = (endTime.getTime()-startTime.getTime())/(60*1000)+1;
		long min1 = min%60;
		long hour =(min/60)%24;
		long day = min/60/24;
		String re = "";
		if(day>0){
			re+=day+"天";
		}
		if(hour>0){
			re+=hour+"小时";
		}
		if(min1>0){
			re+=min1+"分钟";
		}
		return re;
	}


	public void couponPlay(ZsyyParkLeave parkLeave){
		String parkCode = parkLeave.getParkCode();
		if(StringUtils.isEmpty(parkLeave.getCarLicenseNumber())){
			return;
		}
		List<CouponByParkCarDTO> listCou = couponService.getCouponByParkCar(parkLeave.getCarLicenseNumber(),1,parkCode);

		CouponByParkCarDTO coupon = null;
		if(listCou.size()>0){
			//获取优惠券
			coupon = listCou.get(0);

		}else{
			return;
		}
		Integer discount = coupon.getDiscount();
		String orderNo = GeneratorUtil.genOrderId("40","msdw");
		if(parkCode.indexOf("/")==-1){
			Map addParam = new HashMap();
			addParam.put("userId",0);
			addParam.put("type",0);
			Map param = new HashMap();
			param.put("parkCode",parkCode);
			param.put("carCode",parkLeave.getCarLicenseNumber());
			String data = toZhtcApiService.privateApi("getParkFee", JSON.toJSONString(param),addParam);
			Map m = JSON.parseObject(data,Map.class);
			if(Integer.parseInt(m.get("status").toString()) != 1){
				return ;
			}
			Map dataM = (Map)m.get("data");
			ZsyyParkEnter peParam = new ZsyyParkEnter();
			peParam.setParkingCode(dataM.get("parkingCode").toString());
			int price = (int)(Double.parseDouble(dataM.get("shouldPayValue").toString())*100);
			if(price>0){
				Map parkData = new HashMap();
				parkData.put("parkCode",parkCode);//停车场编码
				parkData.put("parkingCode",parkLeave.getParkingCode());//停车编号
				parkData.put("chargeDate",dataM.get("enterDate"));//计费时间
				parkData.put("payDate", DateUtil.format(new Date(),"yyyyMMddHHmmss"));//支付时间
				parkData.put("paymentMode",4);//支付方式
				parkData.put("payOrigin",4);//支付来源
				parkData.put("billCode",orderNo);//第三方订单号
				parkData.put("actPayCharge",discount/100d);//支付金额
				String zhtcStr = toZhtcApiService.privateApi("payParkFee ",JSON.toJSONString(parkData),addParam);
				ZhtcRe zhtcRe = JSON.parseObject(zhtcStr,ZhtcRe.class);
				if(zhtcRe.getStatus()==1){
					//付费成功
					//使用优惠券
					userCouponService.useCoupon( coupon.getCouponId());
				}
				return ;
			}
		}else {

			SendplateticketQuery ticket = new SendplateticketQuery();
			ticket.setParkCode(parkCode);
			ticket.setPlateNumber(parkLeave.getCarLicenseNumber());
			ticket.setTicketValue(discount/100);
			ticket.setIsEntrance(0);
			ZhtcRe re = homeParkService.sendplateticket(ticket);

			if(re.getStatus()==1){
				//付费成功
				//使用优惠券
				userCouponService.useCoupon(coupon.getCouponId());
			}
		}

	}
}
